
/*    This file is part of the managarm operating system.
 *   Copyright (C) 2007, 2008, 2009  Alexander van der Grinten
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>. */

package org.managarm.jmanaintlib.machine;

import org.managarm.jmanavalib.core.VaDatatype;

public final class VmCellArray extends VmCell {
	// elements of this array
	private final VmCell[] elements; 
	
	// basetype of this array
	private final VaDatatype.DtArray datatype;
	
	public VmCellArray(VaDatatype.DtArray datatype, long size) {
		this.datatype = datatype;
		
		// very big arrays are not implemented yet
		if(size >= (1L << 31L))
			throw new UnsupportedOperationException("Huge arrays are " +
					"not implemented yet!");
		
		// construct a new element array
		elements = new VmCell[(int)size];
	}
	
	@Override public final VmCell loadElement(long index)
			throws VmError {
		if(index >= elements.length)
			throw new VmError("Illegal array index " + index
					+ " (Size: " + elements.length + ")");
		final VmCell curcell = elements[(int)index];
		if(curcell != null)
			return curcell;
		final VmCell newcell = VmUtils.createCell(datatype.basetype);
		elements[(int)index] = newcell;
		return newcell;
	}
	
	@Override public final void storeElement(long index, VmCell cell) 
			throws VmError {
		if(index >= elements.length)
			throw new VmError("Illegal array index " + index
					+ " (Size: " + elements.length + ")");
		elements[(int)index] = cell;
	}
	
	@Override public final long arraySize() {
		return elements.length;
	}
	
	@Override public void arrayCopy(VmCell source,
			long offset, long srcoffset, long length) throws VmError {
		final long srclimit = srcoffset + length;
		int destpointer = (int)offset;
		while(srcoffset < srclimit) {
			elements[destpointer] = source.loadElement(srcoffset);
			destpointer++;
			srcoffset++;
		}
	}
	
	@Override public VmCell castTo(VaDatatype type) {
		return this;
	}
}
